﻿using GRPCClass;
using Newtonsoft.Json;
 
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace SdtpsNodeLibrary
{
    /// <summary>
    /// 任务执行节点
    /// </summary>
    public class NodeHandle
    {
        static System.Threading.Thread mythd;
        static TaskReplyWorker trw;
        /// <summary>
        /// 启动 
        /// 启动定时心跳线程
        /// 启动任务执行线程
        /// </summary>
        /// <returns></returns>
        public static string Start()
        {
            //开启本地服务
            //StartServer();
            nodeip = getip();
            AppWorker.Host = nodeip;

            AppWorker.Port = SdtpsBase.Util.StrToInt(ConfigurationManager.AppSettings["nodeport"].ToString());
            AppWorker.ID = string.Format("{0}:{1}", AppWorker.Host, AppWorker.Port);
            int mtc = 0;
            if (ConfigurationManager.AppSettings["MaxTaskCount"] != null)
            {
                mtc = SdtpsBase.Util.StrToInt(ConfigurationManager.AppSettings["MaxTaskCount"].ToString());
            }
            if (mtc <= 0)
            {
                mtc = 5000;
            }
            AppWorker.MaxTaskCount = mtc;//节点最大可接受的待处理任务数

            string vs;
            try
            {
                vs = SendEnroll();
            }
            catch (Exception cw)
            {
                if (cw.Message.Contains("Connect Failed"))
                {
                    vs = string.Format("注册到中心服务器异常,请确认服务已开启:{0}", cw.Message);
                }
                else
                {
                    vs = string.Format("注册到中心服务器异常:{0}", cw.Message);
                }
            }
            mythd = new System.Threading.Thread(new System.Threading.ThreadStart(HeartBeat));
            mythd.Start();

            mytw = new TaskWorker();
            mytw.Start();
            trw = new TaskReplyWorker();
            trw.Start();
            return vs;
        }
        private static bool _isstop;
        public static bool IsStop
        {
            get
            {
                return _isstop;
            }
            set
            {
                _isstop = value;
                mytw.isStop = value;
                trw.isStop = value;
                if (value)
                {
                    LogoutNode();
                }
                else
                {
                    SendEnroll();
                }
            }
        }
        private static TaskWorker mytw;
        /// <summary>
        /// 当前执行的任务的对象
        /// </summary>
        public static TaskWorker AppTaskWorker
        {
            get
            {
                return mytw;
            }
            set
            {
                mytw = value;
            }
        }

        const int timehear = 30000;//30秒反馈一次
       public static Worker AppWorker=new Worker();
        static SdtpsRPCSDK.GRPCClient mygc = new SdtpsRPCSDK.GRPCClient();
        /// <summary>
        /// 注册执行节点到中心节点
        /// </summary>
        /// <returns></returns>
        public static string SendEnroll()
        {
            TaskRequest mytr = new TaskRequest();
            mytr.ID = Guid.NewGuid().ToString();
            mytr.Name = "执行节点";
            mytr.CreateTime = DateTime.Now.ToString();
            mytr.TaskType = "node";
            mytr.TryCount = 3;
            mytr.OverTimeDuration = 1000;
           
            mytr.Param = JsonConvert.SerializeObject(AppWorker);

           

            string sadd = ConfigurationManager.AppSettings["centerhandleip"].ToString();
            string port = ConfigurationManager.AppSettings["centerhandleport"].ToString();
            mygc.Servadd = string.Format("{0}:{1}", sadd, port);

            TaskReply mygt = mygc.EnrollNode(mytr);
            return mygt.Message;

        }
        /// <summary>
        /// 注销当前的执行节点
        /// </summary>
        /// <returns></returns>
        public static string LogoutNode()
        {
            TaskRequest mytr = new TaskRequest();
            mytr.ID = Guid.NewGuid().ToString();
            mytr.Name = "执行节点";
            mytr.CreateTime = DateTime.Now.ToString();
            mytr.TaskType = "node";
            mytr.TryCount = 3;
            mytr.OverTimeDuration = 1000;

            mytr.Param = JsonConvert.SerializeObject(AppWorker);



            string sadd = ConfigurationManager.AppSettings["centerhandleip"].ToString();
            string port = ConfigurationManager.AppSettings["centerhandleport"].ToString();
            mygc.Servadd = string.Format("{0}:{1}", sadd, port);

            TaskReply mygt = mygc.LogoutNode(mytr);
            return mygt.Message;
        }
            public static string getip()
        {
            string ipadd = "";
            IPAddress[] ipArray;
            ipArray = Dns.GetHostAddresses(Dns.GetHostName());
            for (int i = 0; i < ipArray.Length; i++)
            {
                if (!ipArray[i].IsIPv6LinkLocal)
                {
                    if (ipArray[i].AddressFamily.ToString() == "InterNetwork")
                    {
                        ipadd = ipArray[i].ToString();
                    }
                }
            }
            return ipadd;
        }
        static string nodeip;
        /// <summary>
        /// 开启心跳服务
        /// </summary>
        public static void HeartBeat()
        {


            do
            {
                try
                {
                    SendEnroll();
                }
                catch (Exception cw)
                {
                    filelog(string.Format("HeartBeat异常\t{0} {1} {2}", nodeip, AppWorker.Port, cw.Message));
                }
                System.Threading.Thread.Sleep(timehear); 
            }
            while (!IsStop);
        }
        /// <summary>
        /// 记录文件日志
        /// </summary>
        /// <param name="text"></param>
        static void filelog(String text)
        {
            string fullname = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"runlogs\runNodeHandle.log");

            SdtpsBase.Util.WriteText(fullname, string.Format("{0}\t{1}\r\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), text), 1024 * 1024 * 2);
        }


    }
}
